﻿using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using HQPad.Services;
using HQPad.DAL;
using HQPad.Models;
using Sib = Siberix.Report;

namespace HQPad.Helpers
{
    public class BattleboardHelper
    {
        private BattleboardModel model = null;

        public BattleboardHelper(BattleboardModel model)
        {
            this.model = model;
        }

        public byte[] GenerateBattleboard(string boardType)
        {
            byte[] content = null;

            // Select the correct xml document for the selected board.
            string boardName = "Standard.xml"; // todo: expand for different types.

            // make report.
            content = PrepareReport(boardName);

            return content;
        }


        protected byte[] PrepareReport(string boardName)
        {

            Sib.Report report = new Sib.Report();

            string reportPath = string.Format("/xml/battleboard/{0}", boardName);

            // Load default xml document.
            string reportFormatPath = HttpContext.Current.Server.MapPath(reportPath);

            XmlDocument doc = new XmlDocument();
            doc.Load(reportFormatPath);
            string xml = doc.OuterXml;

            // Fix dynamic magic and life section heights.
            xml = FixLifeAndMagicHeights(xml);

            // Fix dynamic power section height.
            xml = FixPowerHeight(xml);

            // replace font paths.
            //string fontPath = HttpContext.Current.Server.MapPath("/fonts/");
            //if (!fontPath.EndsWith("/"))
            //    fontPath = fontPath + "/";
            //xml = xml.Replace("{FontPath}", fontPath);


            BattleboardCallback callback = new BattleboardCallback(model);
            report.Callback = callback;

            //report.Load(reportFormatPath);
            StringReader stringReader = new StringReader(xml);
            XmlTextReader xmlReader = new XmlTextReader(stringReader);
            report.Load(xmlReader);

            System.IO.MemoryStream ms = new System.IO.MemoryStream();

            report.Publish(ms, Sib.FileFormat.PDF);

            return ms.ToArray();
        }

        protected string FixLifeAndMagicHeights(string xml)
        {
            int magicRowheight = 15;
            int magicHeadersHeight = 30;
            int totalHeight = 340;

            string lifeHeight = "100%";
            string magicHeight = "0";
            bool anyMagic = false;

            if (model.Spells != null && model.Spells.Count > 0)
            {
                int height = magicRowheight * model.Spells.Count;

                if (model.Spells.Count >= 5)
                    height += (magicRowheight * 2);

                magicHeight = (magicHeadersHeight + height).ToString();
                lifeHeight = (totalHeight - (height + magicHeadersHeight)).ToString();
            }

            for (int i = 1; i <= 10; i++)
            {
                string key = string.Format("{{SpellSlot_Level_{0}_Height}}", i);

                SpellLevelSlot slotLevel = model.Spells.Where(a => a.Level == i).FirstOrDefault();

                int val = 0;

                if (slotLevel != null)
                {
                    anyMagic = true;

                    if (slotLevel.Level == 5)
                        val = (magicRowheight * 3);
                    else
                        val = magicRowheight;
                }
                else
                {
                    // remove section
                    int start = xml.IndexOf(string.Format("<!-- level {0} slots -->", i));
                    int end = xml.IndexOf(string.Format("<!-- level {0} slots end -->", i));

                    xml = xml.Remove(start, end - start);
                }

                xml = xml.Replace(key, val.ToString());
            }

            if (!anyMagic)
            {
                // remove section
                int start = xml.IndexOf("<!-- Magic -->");
                int end = xml.IndexOf("<!-- Magic end -->");

                xml = xml.Remove(start, end - start);
            }

            return xml.Replace("{Life_Height}", lifeHeight).Replace("{Magic_Height}", magicHeight);
        }

        protected string FixPowerHeight(string xml)
        {
            string height = "70";
            
            if (model.TotalPower > 50)
            {
                height = "150";
            }

            return xml.Replace("{Power_Height}", height);
        }
    }
}